Repository navigation
Reuse VJPs in GeomSum and ManualIter fixed-point gradients - #486
Conversation
lkdvos
left a comment
There was a problem hiding this comment.
actually looking at this a bit more, I wonder if we can also speed up the solvers by creating the following 3 functions to compute vjp's for:
f(state, env) = gauge_fixed_iteration(state, env) # both
g = Base.Fix1(f, state)
h = Base.Fix2(f, env)It might be worth investigating if these vjp's are faster.
In any case, good catch, this does seem like it should speed up the gradients!
|
Can we do this in a follow up, so changes will be restricted to GeomSum and ManualIter? |
lkdvos
left a comment
There was a problem hiding this comment.
left some minor comments about the docstrings but otherwise good to go for me, definitely also okay to put the other changes in a different PR.
leburgel
left a comment
There was a problem hiding this comment.
Up to a few very minor naming comments, looks perfect to me.
On the Fix1/Fix2 idea: I don’t think that will make a difference. Zygote differentiates through captured fields of a closure, so the state captured in Fix1(f, state) is still tracked, and TensorOperations will still compute (and force) the ket/bra cotangents on every pullback call. I first tried this approach in #430 hoping for a speedup, but it turned out that capturing the state in a closure gave identical allocations to passing it as an argument, which I was very annoyed about.
The only thing that helped was reading the local sandwich through a custom constant_site getindex helper whose gradient is explicitly ignored, so that the state cotangents are never tracked in the pure-environment VJP used in the linear solves.
I then gave up on doing the same for FixedPointGradient, since plumbing a similar hook all the way deep inside a CTMRG iteration was a total pain. Maybe with Enzyme the Fix1/Fix2 idea would work, but with our current setup it makes no difference.
|
New changes:
|
BenchmarkMeasurements cover Values below are upstream → current; percentage changes are relative to upstream, so negative values indicate reductions. Heisenberg, D = 3, χ = 12
|
| # fix global phases relative to the fixed point inside the iteration | ||
| return fix_global_phases( | ||
| fix_relative_phases(ctmrg_iteration(InfiniteSquareNetwork(A), x, alg_fixed)[1], signs), | ||
| fix_relative_phases(ctmrg_iteration(InfiniteSquareNetwork(p), x, alg_fixed)[1], signs), |
There was a problem hiding this comment.
@lkdvos Should we wrap alg_fixed, signs, env in ignore_derivatives? I did some tests; it has almost no effect on performance except a tiny reduction in allocations.
In fixed-point gradient calculation, GeomSum and ManualIter previously called the same CTMRG pullback separately for its parameter
pand environmentxcotangents. Both solvers now accept a joint VJP and reuse both outputs, avoiding a redundant reverse pass per iteration:Update the fixedpoint_gradient docstring to describe the joint-VJP signature, and rename ∂f∂A to ∂f∂p to match the parameter
pnotation.I find the notation
dx,dyconfusing, and will try to come up with more descriptive names as I learn about them.